#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <LPC23xx.H>
#include "bas_fun.h"
#include "uart_fun.h"
#include "aio_fun.h"
#include "net_fun.h"
#include "rtu_file.h"

#ifdef WEB_FUN
#include "web_fun.h"

#ifdef MCI_FUN
#include "mci_ff.h"
#include "mci_fun.h"
#endif

//#define WEB_DEBUG
short web_net_path=-1;
/*
const unsigned char GetResponse[] =              // 1st thing our server sends to a client
{
  "HTTP/1.1 200 OK\r\n"                          // protocol ver 1.1, code 200, reason OK
  "Content-Type: text/html\r\n"                  // type of data we want to send
  "\r\n"                                         // indicate end of HTTP-header
};
*/
char cgi_chkch(char *s1,char s2)
{
    if (strchr(s1,s2) != 0) return(1);
    else return(0);
}

char cgi_chkstr(char *s1,char *s2)
{
    if (strstr(s1,s2) != 0) return(1);
    else return(0);
}

char strscomp(const char *s1, const char *s2)
{ 
    if (strlen(s1) != strlen(s2)) return(0);
    //if ((strncmp(s1,s2,strlen(s1))) != 0) return(0);
    if (strcmp(s1,s2) != 0) return(0);
    return(1);
}

char cgi_dec(char *s,char *rcv,char *str,char end)
{
    char *ptr0, *ptr1;
    unsigned char len, rcvlen;
 
    if ((ptr0=strstr(s,str))==0) return(0);
	len=strlen((const char*) str);
	ptr0=ptr0+len;
	   
	if ((ptr1=strchr(ptr0,end))==0) return(0);
	rcvlen=ptr1-ptr0;

	memcpy(rcv,ptr0,rcvlen);
	rcv[rcvlen]='\0';
	return(1);
}

char get_httphex(char *s,unsigned char *i,int *cint)
{
    U8  j=0,n=0;
    S8  var[10];
	
    (*cint)=0;
    while(c_hex(s[*i])<0) { 
        if (s[*i]==0) return(0);
	    (*i)++;
    }
	
    while(c_hex(s[*i])>=0) { var[j]=s[*i]; j++;  (*i)++; if (++n>=2) break; }
    if (j==0) return(0);

    var[j]=0; (*cint)=hatoi(var);
    return(1);
}

void cgi_str_hex(char *s,char *p)
{
    unsigned char len,i,n=0;
	
	len=strlen(s);
	for (i=0;i<len;i++) {
	    if (s[i]!='%') p[n++]=s[i];
		else {
		    i++;
		    p[n++]=(c_hex(s[i])*16+(c_hex(s[i+1])));
			i++;
		}
	}
	p[n]='\0';
}

#define PAGE_NUM   16
unsigned short aio_id;
short aio_ch;
#define MSGB_PAGE_NUM   20
#define PAGE_END_NUM    1000
short msgb_ch=PAGE_END_NUM;

int pwr_chk=0;
void http_cgi(void)
{
    char /*user_temp[LOGIN_MAX_BUFF_SIZE]={" "},*/ pass_temp[LOGIN_MAX_BUFF_SIZE]={" "}; 
	char *s,*ptr,c[64];
	int  p[6],sidx,len;
	unsigned short n;
   
	if ((s=(char *)uart_rx_buf(web_net_path))==0) return;
	len=uart_rx_rdy(web_net_path);
	s[len]=0;
	sidx=len-30;
	if (sidx<0) sidx=0;
	
    switch(http_page) {
	    case _LOGIN_CGI:
            if (!cgi_chkstr((char *)(s+sidx),"Login")) break;

            //if (!cgi_dec(s,user_temp,"username=",'&')) break;
	        if (!cgi_dec(s,pass_temp,"password=",'&')) break;
		
	        //if ((strscomp((const char*) http_user,(const char*) user_temp)) && 
	        //    (strscomp((const char*) http_passw,(const char*) pass_temp))) {
		    if ((strscomp((const char*) http_passw,(const char*) pass_temp))) {
			    pwr_chk=1;
	            http_page=_DEFAULT_CGI; 
	        }
	        else { http_page=_LOGIN_CGI; }
	        break;

        case _DEFAULT_CGI:   
            break;

        case _LEFT_CGI:
            break;

	    case _SYSTEM_CGI:
	        break;

        case _AI_CGI: 
		case _DI_CGI:
		case _DO_CGI:
		    if (cgi_chkstr((char *)(s+sidx),"Last+ID")) { aio_id--; aio_ch=0; }
		    else if (cgi_chkstr((char *)(s+sidx),"Next+ID")) { aio_id++; aio_ch=0; }
		    else if (cgi_chkstr((char *)(s+sidx),"Last+Page")) aio_ch-=PAGE_NUM;
			else if (cgi_chkstr((char *)(s+sidx),"Next+Page")) aio_ch+=PAGE_NUM;
		    break;

		case _HISTORY_CGI:
			if (cgi_chkstr((char *)(s+sidx),"Home"))      msgb_ch=0;
			else if (cgi_chkstr((char *)(s+sidx),"End"))       msgb_ch=PAGE_END_NUM; 
		    else if (cgi_chkstr((char *)(s+sidx),"Last+Page")) msgb_ch-=MSGB_PAGE_NUM;
			else if (cgi_chkstr((char *)(s+sidx),"Next+Page")) msgb_ch+=MSGB_PAGE_NUM;	    		   
		    break;

        case _SYSCONF_CGI:
		    if (!cgi_chkstr((char *)s,"Save")) break; 
		 
		    if (cgi_dec(s,c,"Site=",'&')) {
                cgi_str_hex(c,sys_site);
#ifdef WEB_DEBUG
			    Dprintf("#_SYSCONF_CGI Site=%s\n",sys_site);
#endif
				I2C_WriteBytes(HW_STATION,(unsigned char *) &sys_site,20);
            }		  

		    if (cgi_dec(s,c,"Location=",'&')) {
		 	    cgi_str_hex(c,sys_location);
#ifdef WEB_DEBUG
			    Dprintf("#_SYSCONF_CGI Location=%s\n",sys_location);
#endif
				I2C_WriteBytes(HW_LOCATION,(unsigned char *) &sys_location,20);
            } 
		    break;

	    case _NET_CGI:
            if (!cgi_chkstr((char *) s,"Save")) break;

			for (n=0; n<NIP_NUM; n++) {
			    sprintf(http_msg,"ip%d=",n);
 		        if ((ptr=strstr(s,http_msg)) != 0) {
                    sscanf ((const S8 *)&ptr[4], "%d.%d.%d.%d",&p[0],&p[1],&p[2],&p[3]);
			        if ((p[0]<=255)&&(p[1]<=255)&&(p[2]<=255)&&(p[3]<=255)) {
			            N_MyIP[n][0] = p[0]+(p[1] << 8);             
                        N_MyIP[n][1] = p[2]+(p[3] << 8);  
			           	I2C_WriteBytes(I2C_MyIP+(20*n),(unsigned char *)N_MyIP[n],4); 
					    I2C_ReadBytes(I2C_MyIP+(20*n),(unsigned char *)N_MyIP[n],4); 
			        }
                } 
			    sprintf(http_msg,"gateway%d=",n);
 		        if ((ptr=strstr(s,http_msg)) != 0) {
                    sscanf ((const S8 *)&ptr[9], "%d.%d.%d.%d",&p[0],&p[1],&p[2],&p[3]);
			        if ((p[0]<=255)&&(p[1]<=255)&&(p[2]<=255)&&(p[3]<=255)) {
			            N_GatewayIP[n][0] = p[0]+(p[1] << 8);             
                        N_GatewayIP[n][1] = p[2]+(p[3] << 8); 
			            I2C_WriteBytes(I2C_GatewayIP+(20*n),(unsigned char *)N_GatewayIP[n],4);  
					    I2C_ReadBytes(I2C_GatewayIP+(20*n),(unsigned char *)N_GatewayIP[n],4); 
			        }
                }  
			    sprintf(http_msg,"mask%d=",n);
 		        if ((ptr=strstr(s,http_msg)) != 0) {
                    sscanf ((const S8 *)&ptr[6], "%d.%d.%d.%d",&p[0],&p[1],&p[2],&p[3]);
			        if ((p[0]<=255)&&(p[1]<=255)&&(p[2]<=255)&&(p[3]<=255)) {
			            N_SubnetMask[n][0] = p[0]+(p[1] << 8);             
                        N_SubnetMask[n][1] = p[2]+(p[3] << 8); 
				        I2C_WriteBytes(I2C_SubnetMask+(20*n),(unsigned char *)N_SubnetMask[n],4); 
					    I2C_ReadBytes(I2C_SubnetMask+(20*n),(unsigned char *)N_SubnetMask[n],4);
			        }
                }
			}
	        break;

        case _CHGPASSW_CGI:
		    /*		
		    if (!cgi_chkstr((char *) s,"Submit")) break;

            if (cgi_dec(s,c,"password=",'&')) {
			    if (strlen(c)<=LOGIN_MAX_BUFF_SIZE) {
			        sprintf(http_passw,"%s",c);
					//memcpy(http_passw, c, strlen((const char*) c));
				    I2C_WriteBytes(HW_PW_ADDR,(unsigned char *) &http_passw,4);
			        //Dprintf("#_CPASSWORD_CGI  New Password=%s\n",http_passw);
			    }
		    }
			*/
	        break;

	    default:
	        break; 
    }  
}

void http_rev(void)
{
    unsigned char http_type=HTTP_HEAD;
    unsigned char pagenum;
    char *s,*p;
    HTTP_FILE *ptr=0;

	if (http_flag) { uart_rx_clr_port(web_net_path); return; }
    if ((s=(char *)uart_rx_buf(web_net_path))==0) return;
	WebOffSec=0;

    //dputstr(1,s);
    if (strstr((char *) s,HTTP_Method_String[0]) != 0) { http_type=HTTP_GET; }
    else if (strstr((char *) s,HTTP_Method_String[1]) != 0) { http_type=HTTP_POST; }

	http_flag=HTTP_SENDFLAG;
    switch(http_type) {
        case HTTP_GET: 
#ifdef WEB_DEBUG
	        Dprintf("#HTTP_GET \n");
#endif		
	        if (strstr(s,"GET / HTTP/1.1") != 0) { http_page=_LOGIN_CGI; break; }

		    if (!pwr_chk) {
	            sprintf(http_msg,"GET /%s HTTP/1.1","Login.htm");
			    if (strstr(s,(char *) &http_msg) != 0) { http_page=_LOGIN_CGI; break; }
	            sprintf(http_msg,"GET /%s HTTP/1.1","index.gif");
			    if (strstr(s,(char *) &http_msg) != 0) { http_page=_INDEX_JPG; break; }		  
		     
			    http_page=_LOGIN_CGI; break; 
	        }

	        for (pagenum=0; pagenum<FileCnt; pagenum++) {
	            ptr=(HTTP_FILE *) &FileTab[pagenum];
			    sprintf(http_msg,"GET /%s HTTP/1.1",ptr->Name);
			    if (strstr(s,(char *) &http_msg) != 0) { http_page=pagenum; break; }
	        }

#ifdef WEB_DEBUG
	        Dprintf("#HTTP_GET: %s\n",ptr->Name);
#endif

            if (pagenum!=FileCnt) break;

		    if ((p=strstr(s,"GET /")) != 0) {
		        http_page=pagenum;
		        sscanf ((const S8 *)&p[5], "%s",http_fn);
		    }  
            break;

	    case HTTP_POST:	
	        for (pagenum=0; pagenum<FileCnt; pagenum++) {
	            ptr=(HTTP_FILE *) &FileTab[pagenum];
			    sprintf(http_msg,"POST /%s HTTP/1.1",ptr->Name);
			    if (strstr(s,(char *) &http_msg) != 0) { http_page=pagenum; break; }
	        }	 
#ifdef WEB_DEBUG
		    Dprintf("#HTTP_POST: %s\n",ptr->Name);
#endif	 
            http_cgi();	
	        break;

	    case HTTP_HEAD:
	    default:
#ifdef WEB_DEBUG
		    Dprintf("#HTTP_HEAD:\n");
#endif
	        break;
    }
    uart_rx_clr_port(web_net_path);
}

void system_info(void)
{
    char *s,*ptr;
    unsigned short n;

	if ((s=(char *)uart_tx_buf(web_net_path))==0) return;

    ptr=s;
    //site
    if ((ptr=strstr(ptr,"&site;")) != 0) {
        sprintf(http_msg,"%6s", strlen(sys_site) ? sys_site : "   ");
        memcpy(ptr, http_msg, strlen((const char*) http_msg));
    }
	else ptr=s;
	//loaction
    if ((ptr=strstr(ptr,"&loca;")) != 0) {
        sprintf(http_msg,"%6s", strlen(sys_location) ? sys_location : "   ");
        memcpy(ptr, http_msg, strlen((const char*) http_msg));
    }
	else ptr=s;
	//version
    if ((ptr=strstr(ptr,"&version;")) != 0) {
        sprintf(http_msg,"V%d.%02d_%d/%02d/%02d",ver_h,ver_l,ver_yy,ver_mn,ver_dd);
        memcpy(ptr, http_msg, strlen((const char*) http_msg));
    }
	else ptr=s;
	
	//ID Address
    if ((ptr=strstr(ptr,"&addr;")) != 0) {
        sprintf(http_msg,"%6d",mrs_id);
        memcpy(ptr, http_msg, strlen((const char*) http_msg));
    }
	else ptr=s;  
	//Protocol
    if ((ptr=strstr(ptr,"&pro;")) != 0) {
        sprintf(http_msg,"%5s","Modbus");
        memcpy(ptr, http_msg, strlen((const char*) http_msg));
    }
	else ptr=s;
    // Net
    if ((ptr=strstr(ptr,"&mac;")) != 0) {
        sprintf(http_msg,"%x. %x. %x. %x. %x. %x",MyMAC[0],MyMAC[1],MyMAC[2],MyMAC[3],MyMAC[4],MyMAC[5]);
        memcpy(ptr, http_msg, strlen((const char*) http_msg));
    }
	else ptr=s;
 	
	for (n=0; n<NIP_NUM; n++) {
	    sprintf(http_msg,"&ip%d",n); 
        if ((ptr=strstr(ptr,http_msg)) != 0) {
            sprintf(http_msg,"%d. %d. %d. %d",
			    N_MyIP[n][0]&0xff,N_MyIP[n][0]>>8,N_MyIP[n][1]&0xff,N_MyIP[n][1]>>8);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        } 
		else ptr=s;
		
	    sprintf(http_msg,"&mask%d",n); 
        if ((ptr=strstr(ptr,http_msg)) != 0) {
            sprintf(http_msg,"%d. %d. %d. %d",
			    N_SubnetMask[n][0]&0xff,N_SubnetMask[n][0]>>8,N_SubnetMask[n][1]&0xff,N_SubnetMask[n][1]>>8);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        }
		else ptr=s;
						 
		sprintf(http_msg,"&gateway%d",n); 
        if ((ptr=strstr(ptr,http_msg)) != 0) {
            sprintf(http_msg,"%d. %d. %d. %d",
			    N_GatewayIP[n][0]&0xff,N_GatewayIP[n][0]>>8,N_GatewayIP[n][1]&0xff,N_GatewayIP[n][1]>>8);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        }
		else ptr=s; 												   
	} 
}

unsigned short oj,oi;
void ai_info(void)
{
    char *s,*ptr;
    unsigned short i,j; 

	unsigned short max,sch;
	char     hc;
	short    cno,ch;
	SS_PARM  *pss;

    if ((s=(char *)uart_tx_buf(web_net_path))==0) return;

    if (aio_id>=SS_NUM) aio_id=0; 	 
	pss=(SS_PARM *)&SS[aio_id];	
    hc='a'; max=pss->AIN; sch=pss->AIS; 

    ptr=s;	
	if (!(HTTPStatus & HTTP_SEND_PAGE)) oj=oi=0;
	
	if (!oj) {
		if ((ptr=strstr(ptr,"&id;")) != 0) {
            sprintf(http_msg,"ID: %d",aio_id);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        } 		
		else ptr=s;
				 
        if ((ptr=strstr(ptr,"&ais;")) != 0) {
            sprintf(http_msg,"AI Start: %d",sch);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        }
		else ptr=s;
		 
        if ((ptr=strstr(ptr,"&ain;")) != 0) {
            sprintf(http_msg,"AI Num: %d",max);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        }
		else ptr=s;
	}	 

	if ((aio_ch+PAGE_NUM)>=max) aio_ch=max-PAGE_NUM;
	if (aio_ch<0) aio_ch=0;
	
	for (j=oj; j<PAGE_NUM; j++,cno++,ch++) {
		oj=j; ch=sch+aio_ch+j; cno=aio_ch+j;
		for (i=oi; i<7; i++) {
			oi=i;
			sprintf(http_msg,"&a%d%d;",j,i);
            if ((ptr=strstr(ptr,http_msg)) == 0) return;
			if ((cno<max)&&(ch<MAX_AI_NUM)) {
			    switch(i) {
				    case 0:	sprintf(http_msg,"[%3d] ",cno);                break;
					case 1: sprintf(http_msg,"%6s",no2str(hc,aio_id,cno)); break;
					case 2:	sprintf(http_msg,"%8.5f",(AIP+ch)->bas);       break;
					case 3:	sprintf(http_msg,"%6d",AI_get_count(ch));      break;
					case 4:	sprintf(http_msg,"%6d",AI_get_ibuf(ch));       break;
					case 5:	sprintf(http_msg,"%c     ",qc_menu_code(hc,ch));       break;
					case 6: sprintf(http_msg,"%6s",name_str(hc,ch)); break;
				}
			}
			else sprintf(http_msg,"       ");  					 
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
		}
		oi=0;
	}
}

void di_info(void)
{
    char *s,*ptr;
    unsigned short i,j; 

	char rmodes[5][5]={"   ","   ","   ","SOE","MCD"};
	unsigned short max,sch;
	char     hc;
	short    cno,ch;
	SS_PARM  *pss;

    if ((s=(char *)uart_tx_buf(web_net_path))==0) return;

	if (aio_id>=SS_NUM) aio_id=0;    
	pss=(SS_PARM *)&SS[aio_id];
    hc='i'; max=pss->DIN; sch=pss->DIS; 
    ptr=s;
	if (!(HTTPStatus & HTTP_SEND_PAGE))  oj=oi=0;
	if (!oj) {
		if ((ptr=strstr(ptr,"&id;")) != 0) {
            sprintf(http_msg,"ID: %5d",aio_id);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        } 				 
		else ptr=s;
		
        if ((ptr=strstr(ptr,"&dis;")) != 0) {
            sprintf(http_msg,"%5d",sch);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        }
		else ptr=s;
		 
        if ((ptr=strstr(ptr,"&din;")) != 0) {
            sprintf(http_msg,"%5d",max);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        }
		else ptr=s;		
    }
	if ((aio_ch+PAGE_NUM)>=max) aio_ch=max-PAGE_NUM;
	if (aio_ch<0) aio_ch=0;	  	 
	   
	for (j=oj; j<PAGE_NUM; j++,cno++,ch++) {
		oj=j; ch=sch+aio_ch+j; cno=aio_ch+j;    
		for (i=oi; i<6; i++) {
		    oi=i;
			sprintf(http_msg,"&i%d%d;",j,i);
            if ((ptr=strstr(ptr,http_msg)) == 0) return;	
			if ((cno<max)&&(ch<MAX_DI_NUM)) {
				switch(i) {
					case 0:	sprintf(http_msg,"[%3d] ",cno);                  break;
					case 1: sprintf(http_msg,"%6s",no2str(hc,aio_id,cno)); break;	
					case 2:	sprintf(http_msg,"%6s",rmodes[(DIP+ch)->rmode]); break;
					case 3:	sprintf(http_msg,"%6d  ",IO_stus(hc,ch));        break;
					case 4:	sprintf(http_msg,"%c     ",qc_menu_code(hc,ch));       break;					
					case 5:	sprintf(http_msg,"%6s",name_str(hc,ch));           break;
				}
			}
			else sprintf(http_msg,"      ");   
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
		}
		oi=0;
	}
}

void do_info(void)
{
    char *s,*ptr;
    unsigned short i,j; 

	unsigned short max,sch;
	char     hc;
	short    cno,ch;
	SS_PARM  *pss;

    if ((s=(char *)uart_tx_buf(web_net_path))==0) return;

	if (aio_id>=SS_NUM) aio_id=0;   
	pss=(SS_PARM *)&SS[aio_id]; 
    hc='o'; max=pss->DON; sch=pss->DOS;  

	ptr=s;	   
	if (!(HTTPStatus & HTTP_SEND_PAGE)) oj=oi=0;
	if (!oj) {
	    if ((ptr=strstr(ptr,"&id;")) != 0) {
            sprintf(http_msg,"ID: %5d",aio_id);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        }
		else ptr=s;
		 				 
        if ((ptr=strstr(ptr,"&dos;")) != 0) {
            sprintf(http_msg,"DO Start: %d",sch);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        }
		else ptr=s;
		 
        if ((ptr=strstr(ptr,"&don;")) != 0) {
            sprintf(http_msg,"DO Num: %d",max);
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
        }
		else ptr=s;
	}

	if ((aio_ch+PAGE_NUM)>=max) aio_ch=max-PAGE_NUM;
	if (aio_ch<0) aio_ch=0; 
 	   
	for (j=oj; j<PAGE_NUM; j++,cno++,ch++) {
		oj=j; ch=sch+aio_ch+j; cno=aio_ch+j; 
		for (i=oi; i<4; i++) {
			oi=i;
			sprintf(http_msg,"&o%d%d;",j,i);
            if ((ptr=strstr(ptr,http_msg)) == 0) return; 
		    if ((cno<max)&&(ch<MAX_DO_NUM)) {
				switch(i) {
				    case 0:	sprintf(http_msg,"[%3d] ",cno);                break;
					case 1: sprintf(http_msg,"%6s",no2str(hc,aio_id,cno)); break;	
					case 2:	sprintf(http_msg,"%6d",IO_stus(hc,ch));        break;
					case 3:	sprintf(http_msg,"%6s",name_str(hc,ch));        break;
				}
			}
			else sprintf(http_msg,"      ");     
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
		}
		oi=0;
	 }
}

short msbg_last_ch;
void msgb_info(void)
{
    char *s,*ptr;
	unsigned short i;

	int   j,n,max;
    int   idx,sec,ms,chmd,stus,mode,qcm,ivar,opr;	
    short ch,ssn,cno;
	char  hc;
	U16   yy;
	U8    mn,dd,hh,mm,ss;
	
    char  stus_str[8][6]={"0","1","1-0","0-1","0-1-0","1-0-1","Trip","Close"};
	char  do_str[8][6]={"0","1","#22","#33","#44","Pulse","Trip","Close"};
	char  opr_str[8][6]={"#00","MAN","COM","PLC","#44","#55","#66","#77"};
    char  qcm_str[2][2]={" ","M"};
	char  alml_str[8][4]={"NOR","LOW","#22","#33","HIG","#55","#66","OPR"};
	

    if ((s=(char *)uart_tx_buf(web_net_path))==0) return;
   
	if (!(HTTPStatus & HTTP_SEND_PAGE)) oj=oi=0;  

	msbg_last_ch=msgb_ch;
    max=MSGB_rdy();
	if ((msgb_ch+MSGB_PAGE_NUM)>=max) {
	    msgb_ch=max-MSGB_PAGE_NUM;
		msbg_last_ch=PAGE_END_NUM;
    }
	if (msgb_ch<0) msgb_ch=0;
	n=msgb_ch;
    
	ptr=s;
	for (j=oj; j<MSGB_PAGE_NUM; j++,n++) {
		oj=j;  n=msgb_ch+j;
		if (n>=max) goto LE;
		idx=((*MSGB_t)+n)%MSGB_NUM;
		MSGB_read(idx,&sec,&ms,&chmd,&stus,&mode,&qcm,&ivar,&opr);
		ch=md_data(chmd,&hc,&ssn,&cno); 
		if ((sec==0)||(chmd==0)||(ch<0)) goto LE;

		secs_datetime(sec,&yy,&mn,&dd,&hh,&mm,&ss);	
		for (i=oi; i<6; i++) {
			oi=i;
			sprintf(http_msg,"&h%d%d;",j,i);
            if ((ptr=strstr(ptr,http_msg)) == 0) return; 
			if (n<max) {
				switch(i) {
				    case 0:	
					    sprintf(http_msg,"[%3d] ",n+1);              
						break;
					case 1: 
		                if (mode==MSGB_MODE_SOE) sprintf(http_msg,"%04d/%02d/%02d-%02d:%02d:%02d.%03d",yy,mn,dd,hh,mm,ss,ms);
		                else					 sprintf(http_msg,"%04d/%02d/%02d-%02d:%02d:%02d",yy,mn,dd,hh,mm,ss); 
						break;
					case 2:	
					    sprintf(http_msg,"%6s",no2str(hc,0,cno));   
					    break; 
					case 3:
					    if (hc=='a') sprintf(http_msg,"%5d-%3s\n",ivar,alml_str[stus]);					
						else if (hc=='o') sprintf(http_msg,"%9s\n",do_str[stus]);
		                else         sprintf(http_msg,"%9s\n",stus_str[stus]);
						break;
                    case 4:						
						if (opr) sprintf(http_msg,"%6s\n",opr_str[opr]);					
					    else sprintf(http_msg,"%6s\n",qcm_str[qcm]);
						break;						
					case 5:	
					    sprintf(http_msg,"%6s",name_str(hc,ch)); 					
						break;
				}
			}
			else sprintf(http_msg,"        ");     
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
		}
		oi=0;
        continue;
LE:
        for (i=oi; i<6; i++) {
			oi=i;
			sprintf(http_msg,"&h%d%d;",j,i);
            if ((ptr=strstr(ptr,http_msg)) == 0) return; 
            sprintf(http_msg,"        ");     
            memcpy(ptr, http_msg, strlen((const char*) http_msg));	
		}
		oi=0;
	 }
}

void system_conf(void)
{
    char *s,*ptr;

	if ((s=(char *)uart_tx_buf(web_net_path))==0) return;
	ptr=s;
    //Site
    if ((ptr=strstr(ptr,"Site")) != 0) {
        if ((ptr=strstr(ptr,"value=")) != 0) {
	        sprintf(http_msg,"value=%c%s%c",'"',sys_site,'"');
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
	    }
		else ptr=s; 
    }
	else ptr=s;
	//Location
    if ((ptr=strstr(ptr,"Location")) != 0) {
        if ((ptr=strstr(ptr,"value=")) != 0) {
	        sprintf(http_msg,"value=%c%s%c",'"',sys_location,'"');
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
	    }
		else ptr=s;
    }
	else ptr=s;
}

void net_conf(void)
{
    char *s,*ptr;
	unsigned short n;

	if ((s=(char *)uart_tx_buf(web_net_path))==0) return;
	
	ptr=s;
    if ((ptr=strstr(ptr,"mac")) != 0) {
        if ((ptr=strstr(ptr,"value=")) != 0) {
	        sprintf(http_msg,"value=%c%x.%x.%x.%x.%x.%x%c",'"',MyMAC[0],MyMAC[1],MyMAC[2],MyMAC[3],MyMAC[4],MyMAC[5],'"');
            memcpy(ptr, http_msg, strlen((const char*) http_msg));
	    }
		else ptr=s;
    }
	else ptr=s;
 
	for (n=0; n<NIP_NUM; n++) {
		sprintf(http_msg,"ip%d",n);
        if ((ptr=strstr(ptr,http_msg)) != 0) {
			if ((ptr=strstr(ptr,"value=")) != 0) {
                sprintf(http_msg,"value=%c%d.%d.%d.%d%c",
				    '"',N_MyIP[n][0]&0xff,N_MyIP[n][0]>>8,N_MyIP[n][1]&0xff,N_MyIP[n][1]>>8,'"');
                memcpy(ptr, http_msg, strlen((const char*) http_msg));
			}
			else ptr=s;
        }
		else ptr=s;
		
		sprintf(http_msg,"mask%d",n); 
        if ((ptr=strstr(ptr,http_msg)) != 0) {
			if ((ptr=strstr(ptr,"value=")) != 0) {
				sprintf(http_msg,"value=%c%d.%d.%d.%d%c",
				    '"',N_SubnetMask[n][0]&0xff,N_SubnetMask[n][0]>>8,N_SubnetMask[n][1]&0xff,N_SubnetMask[n][1]>>8,'"');
                memcpy(ptr, http_msg, strlen((const char*) http_msg));
			}
			else ptr=s;
        }			
		else ptr=s;
			  				 
		sprintf(http_msg,"gateway%d",n); 
        if ((ptr=strstr(ptr,http_msg)) != 0) {
			if ((ptr=strstr(ptr,"value=")) != 0) {
				sprintf(http_msg,"value=%c%d.%d.%d.%d%c",
					'"',N_GatewayIP[n][0]&0xff,N_GatewayIP[n][0]>>8,N_GatewayIP[n][1]&0xff,N_GatewayIP[n][1]>>8,'"');
                memcpy(ptr, http_msg, strlen((const char*) http_msg));
			}
			else ptr=s;
        }
		else ptr=s;
	}	 
}

// searches the TX-buffer for special strings and replaces them
// with dynamic values
void InsertDynamicValues(void)
{
    char i,*s,*ptr;

    if (TCPTxDataCount < 4) return;                     // there can't be any special string

	if ((s=(char *)uart_tx_buf(web_net_path))==0) return;
	ptr=s;
	
	for (i=0; i<10; i++) {
        if ((ptr=strstr(ptr,"&mks;"))==0) break;
        sprintf(http_msg,"%12s",ver_mks);
        memcpy(ptr, http_msg, strlen((const char*) http_msg));
	}

    switch (http_page) {
        case _LOGIN_CGI:                  break;	
        case _DEFAULT_CGI:                break; 
        case _LEFT_CGI:                   break;
        case _SYSTEM_CGI:  system_info(); break;
		case _AI_CGI:	   ai_info();	  break;		
		case _DI_CGI:	   di_info();	  break;
		case _DO_CGI:  	   do_info();	  break;
		case _HISTORY_CGI: msgb_info();   break;						
        case _SYSCONF_CGI: system_conf(); break;
        case _NET_CGI:	   net_conf();	  break;
        case _CHGPASSW_CGI:	              break;
        default:                          break; 
    }
}

void http_readsd(FIL file,unsigned char *rbuff,long ofs,long count)
{
	FRESULT  res;
	U32  s2, cnt;

	cnt = count;
	res = f_lseek(&file, ofs);
	put_rc(res);
	if (res == FR_OK) {
#ifdef WEB_DEBUG
	   Dprintf("\r\nfptr = %lu(0x%lX)", file.fptr, file.fptr);
#endif
	}

	res = f_read(&file, rbuff, cnt, &s2);

	if (res != FR_OK) { put_rc(res); return; }
	if (cnt != s2) return;
}

void http_data(void)
{
    unsigned short tno;
	unsigned char  *s;
	int   n,tx_size=0,head_size=0;
    NET_PARM  *pnet=0;
	char GetResponse[250]={" "};

	FIL  file1;
	FRESULT  ret;
	//char fn[32];
	static unsigned char  ctype=0;
	static long ofs_size;

	tno=web_net_path-NET_SPATH;
	if (tno<NET_NUM) {
	    pnet=(NET_PARM  *)&NET[tno];
	}

    if (!http_flag) { HTTPStatus&=~HTTP_SEND_PAGE; return; }
	if (!(pnet->SocketStatus&SOCK_TX_BUF_RELEASED)) return;

	uart_tx_clr_port(web_net_path);
	if ((s=(unsigned char *) uart_tx_buf(web_net_path))==0) return;
	
    if (!(HTTPStatus & HTTP_SEND_PAGE)) { 					        // if called the 1st time
	    if (http_page<FileCnt) {
            HTTPBytesToSend=FileTab[http_page].Size - 1;			// get HTML length, ignore trailing zero
            PWebSide=(unsigned char *) FileTab[http_page].Start;    // pointer to HTML-code

		    if (strstr((const char *) FileTab[http_page].Name,"htm") != 0)     ctype=0;  
		    else if (strstr((const char *)FileTab[http_page].Name,"gif") != 0) ctype=1;
			else if (strstr((const char *)FileTab[http_page].Name,"js") != 0)  ctype=2;

		    sprintf(GetResponse,"HTTP/1.1 200 OK\r\n" 
                                "Content-Type: %s\r\n" 
                                "\r\n",ContentType[ctype]);
	    }
	    else {		
	        ret=f_open(&file1, http_fn, FA_READ);
	        if (ret!=FR_OK) { 
#ifdef WEB_DEBUG
			    Dprintf("#HTTP Download Error %s!!!",http_fn); 
#endif			
                goto httpend; 
			}

		    HTTPBytesToSend=file1.fsize - 1;	          // get HTML length, ignore trailing zero
		    ofs_size=0;
		    sprintf(GetResponse,"HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\n"
							    "Content-Range: bytes 0-%d/%d\r\nContent-Length: %d\r\nServer: ibts-19\r\n"
							    "Accept-Ranges: bytes\r\nContent-Disposition: attachment;\r\n\r\n", //filename=%s;\r\n\r\n
		                        HTTPBytesToSend,HTTPBytesToSend+1,HTTPBytesToSend+1);	      
	    }
	    head_size=strlen(GetResponse);
    }

	if ((HTTPBytesToSend+head_size) > pnet->tx_max_buf) { // transmit a segment of MAX_SIZE
        if (!(HTTPStatus & HTTP_SEND_PAGE)) {             // 1st time, include HTTP-header
		    if (http_page<FileCnt) {
		        memcpy(s, GetResponse, strlen(GetResponse));
		        memcpy(s+strlen(GetResponse), PWebSide, pnet->tx_max_buf-strlen(GetResponse));
				if (ctype==0) {
				    n=pnet->tx_max_buf-1;
				    while(n>0) { if (s[n]=='\n') break; n--; }
				    if (n>0) tx_size=n+1; else tx_size=pnet->tx_max_buf;
				}
				else tx_size=pnet->tx_max_buf;
		    }
		    else {
                memcpy(s, GetResponse, strlen(GetResponse));
			    http_readsd(file1, s+strlen(GetResponse), ofs_size, pnet->tx_max_buf-strlen(GetResponse));			    
			    ofs_size += pnet->tx_max_buf-strlen(GetResponse);
				f_close(&file1);				
				tx_size=pnet->tx_max_buf;				
		    }
            HTTPBytesToSend-=tx_size-strlen(GetResponse);
            PWebSide+=tx_size-strlen(GetResponse);		    
        }
        else {
		    if (http_page<FileCnt) {
                memcpy(s, PWebSide, pnet->tx_max_buf);
				if (ctype==0) {
				    n=pnet->tx_max_buf-1;
				    while(n>0) { if (s[n]=='\n') break; n--; }
				    if (n>0) tx_size=n+1; else tx_size=pnet->tx_max_buf;
				}
				else tx_size=pnet->tx_max_buf;
		    }
		    else {
                ret=f_open(&file1, http_fn, FA_READ);
	            if (ret!=FR_OK) { goto httpend; }

			    http_readsd(file1, s, ofs_size, pnet->tx_max_buf);
			    ofs_size += pnet->tx_max_buf;
			    f_close(&file1);
				tx_size=pnet->tx_max_buf;	
		    } 
            HTTPBytesToSend-=tx_size;
            PWebSide+=tx_size;
        }
        TCPTxDataCount=tx_size;                           // bytes to xfer
		s[TCPTxDataCount]=0;  
	    InsertDynamicValues();                            // exchange some strings...
	    uart_tx(web_net_path,TCPTxDataCount);     
    }   
    else if (HTTPBytesToSend) {                           // transmit leftover bytes

        if (!(HTTPStatus & HTTP_SEND_PAGE)) {             // 1st time, include HTTP-header
		    if (http_page<FileCnt) {
		        memcpy(s, GetResponse, strlen(GetResponse));
		        memcpy(s+strlen(GetResponse), PWebSide, HTTPBytesToSend);
		    }
		    else {
                memcpy(s, GetResponse, strlen(GetResponse));
			    http_readsd(file1, s+strlen(GetResponse), ofs_size, HTTPBytesToSend);
			    ofs_size += HTTPBytesToSend;
			    f_close(&file1);
		    }
		    TCPTxDataCount=HTTPBytesToSend+strlen(GetResponse);   // bytes to xfer		    
        }
	    else {
	        if (http_page<FileCnt) {
                memcpy(s, PWebSide, pnet->tx_max_buf);
	        }
	        else {
                ret=f_open(&file1, http_fn, FA_READ);
	            if (ret!=FR_OK) { goto httpend; }
		        http_readsd(file1, s, ofs_size, HTTPBytesToSend);
		        ofs_size += HTTPBytesToSend;
		        f_close(&file1);
	        }
		    TCPTxDataCount=HTTPBytesToSend;               // bytes to xfer
	    }
		
		s[TCPTxDataCount]=0;
	    InsertDynamicValues();                            // exchange some strings...
        uart_tx(web_net_path, TCPTxDataCount);

httpend:
        TCPClose(tno);                                    // and close connection
        HTTPBytesToSend = 0;                              // all data sent
	    HTTPStatus&=~HTTP_SEND_PAGE;                      // reset help-flag if not connected
	    http_flag=0;
	    return;
    }

    HTTPStatus|=HTTP_SEND_PAGE;                           // ok, 1st loop executed 
}


void init_web(short port,unsigned char *ip,short prot)
{
	if (port<NET_SPATH) return;
	else web_net_path=net_create(-1,ip,port,prot);
    Dprintf("web_fun net ip='%s' port=%d path=%d\n",ip,port,web_net_path);
	ver_h=VER_H; ver_l=VER_L; ver_yy=VER_YY; ver_mn=VER_MN; ver_dd=VER_DD;
    sprintf(ver_mks,"%s",VER_MKS);
}

void web_pro(void)
{   
    unsigned short tno;
    NET_PARM  *pnet;

	tno=web_net_path-NET_SPATH;
	if (tno<NET_NUM) {
	    pnet=(NET_PARM  *)&NET[tno];
	    if (pnet->tx_head!=pnet->tx_tail) net_tx_int_ena(web_net_path);
	    // listen for incoming TCP-connection
	    if (pnet->nprotocol==PROT_TCP) {
		    TCPPassiveOpen(tno);  
		    net_TCP_PRO(tno);
			pnet->webnet=1;
	    }
	}

    if (WebOffSec>=300) { WebOffSec=0; pwr_chk=0; aio_ch=0; msgb_ch=PAGE_END_NUM; }
	if (uart_rx_rdy(web_net_path)) http_rev();
	http_data();
}

#endif
